home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
embedded
/
mcu
/
dtmf.arc
/
DTMF11.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-12-17
|
4KB
|
152 lines
* File: DTMF11.ASM
* Driver routines for 68HC11 to produce DTMF tones in software
* this version uses a fixed 256 byte sine table, and a fixed 128 us sample time
* this allows operation under interrupt control
* hardware requirements: 8 bit DAC on port b of 68HC11
* To use, do a JSR to DTINIT to set up timer
* then do a JSR to location DTMF with the digit in the lower nibble of
* Accumulator A
* digit values: 0-9, 10 = #, 11 = *, 12-15 represent a through d
* A 60 ms tone burst will be generated, followed by 60 ms of silence
* The location TTIME may be altered to change this timing
asct
* First a few definitions
io equ $1000 offset for i/o registers
deftt equ 60 default tone time (60 ms)
dac equ io+4 DAC output on port a
tcnt equ io+$e timer free running counter
ocr1 equ io+$16 output compare register
tmsk1 equ io+$22 int mask register
tflg1 equ io+$23 int flag register
ocie equ $80 output compare interrupt enable
intcnt equ 128*2 count to load into output compare
row1 equ 23 row intervals
row2 equ 25
row3 equ 28
row4 equ 31
col1 equ 40 column intervals
col2 equ 44
col3 equ 48
col4 equ 54
org $0 RAM scratchpad - move this to fit your system
ttime rmb 1 tone time in milliseconds
ttctr rmb 2 time counter
ttsave rmb 2 save the count value for interdigit pause
ttflag rmb 1 non zero means generate tones
rowptr rmb 2 next row sample to load
colptr rmb 2 ditto for columns
rowint rmb 1 row interval - added to row counter each sample
colint rmb 1 ditto for column
sample rmb 1 temp storage for sample
* sine is the 256 byte sine wave table
* this must be located on a page boundary! (ie lower 8 bits of address = 0)
org $1000
include sine56.asm
dtinit ldaa #deftt set up time counter
staa ttime
ldaa #$80 set dac to halfway point
staa dac
clr ttflag no tones please
sei set up timer - first disable interrupts
ldd tcnt freeze counter
addd #intcnt
std ocr1
ldaa #ocie
staa tmsk1
staa tflg1 clear flag if set
cli
rts done for now
dtmf anda #$0f clear out junk
tab get row interval
ldx #rowtab
abx
ldaa ,x
staa rowint
ldaa rowtab-coltab,x and column
staa colint
ldd #sine
std rowptr start at 0
std colptr
ldaa ttime start tone - set time
ldab #250 adjust for # of samples in (ttime) msec
mul (125/128) * ttime * 4
lsrd
lsrd
lsrd
lsrd
lsrd
lsrd
std ttsave save for pause time
std ttctr
inc ttflag start tones
dtmf1 brset ttflag,#1,dtmf1 loop till tone complete
ldd ttsave now do pause
std ttctr
clr rowint do the pause by not moving pointers
clr colint
inc ttflag start pause
dtmf2 brset ttflag,#0,dtmf2
rts done
* timer interrupt service routine
* if ttctr != 0, then output next sample to dac
tisr ldd ocr1 (5) add timer count
addd #intcnt (4)
std ocr1 (5)
ldaa #ocie (2) clear flag
staa tmsk1 (4)
brclr ttflag,#1,tisr1 (6) don't generate tone if flag cleared
ldx rowptr (4) get next row sample
ldy colptr (5)
ldaa ,y (5) get column sample
asra (2) divide by 4
asra (2) divide by 4
adda ,y (5) now have 1.25 * column sample
adda ,x (4) add in row sample
eora #$80 (2) fix sign bit
staa dac (4)
xgdx (3) step to next lookup value - first row ...
addb rowint (3)
std rowptr (4)
xgdy (4) ... then column ...
addb colint (3)
std colptr (4)
ldd ttctr (4) decrement timer
subd #1 (4)
std ttctr (4)
bne tisr1 (3) did count go to zero ?
clr ttflag ( ) yes - turn off tones
tisr1 rti (12)
* (12) interrupt response
* ===
* 119 cycles when generating tones
* total overhead at 2 MHz E clock = 119/256 == 46%
coltab fcb col2,col1,col2,col3 0,1,2,3
fcb col1,col2,col3 4,5,6
fcb col1,col2,col3 7,8,9
fcb col1,col3 #,*
fcb col4,col4,col4,col4 a,b,c,d
rowtab fcb row4,row1,row1,row1 0,1,2,3
fcb row2,row2,row2 4,5,6
fcb row3,row3,row3 7,8,9
fcb row4,row4 #,*
fcb row1,row2,row3,row4 a,b,c,d
end